<template>
  <div class="edit-user">
    <hm-header>
      <template #center>编辑资料</template>
    </hm-header>

    <div class="avator">
      <img :src="userInfo.head_img | imgUrl" alt="">
      <van-uploader class="file-uploader" :after-read="afterRead" />
    </div>

    <!-- 图片裁切工具 -->
    <div class="vue-cropper-box"
        v-if="isShowCropper">
        <vueCropper
          ref="cropper"
          :img="option.img"
          :outputType="option.outputType"
          :info="option.info"
          :autoCrop="option.autoCrop"
          :fixed="option.fixed"
          :autoCropWidth="option.autoCropWidth"
          :autoCropHeight="option.autoCropHeight">
        </vueCropper>

        <!-- 按钮 -->
        <van-button class="crop-btn confirm-btn" type="primary" @click="confirmCrop">确认裁剪</van-button>
        <van-button class="crop-btn cancle-btn" type="danger" @click="cancleCrop">取消</van-button>
    </div>

    <hm-nav name="昵称" :desc="userInfo.nickname" @click.native="showEditNicknameDia"></hm-nav>
    <hm-nav name="密码" desc="******" @click.native="showEditPasswordDia"></hm-nav>
    <hm-nav name="性别" :desc="userInfo.gender === 1 ? '男' : '女'" @click.native="showEditGenderDia"></hm-nav>

    <!-- 编辑昵称的对话框 -->
    <van-dialog
      v-model="isShowEditNickname"
      title="编辑昵称"
      show-cancel-button
      @confirm="editNickname">
      <van-field v-model="newNickname"/>
    </van-dialog>

    <!-- 编辑密码的对话框 -->
    <van-dialog
      v-model="isShowEditPassword"
      title="编辑密码"
      show-cancel-button
      @confirm="editPassword"
      @closed="closeEditPasswordDia">
      <van-field
      v-model="newPassword"
      :type="canSeePassword ? 'text' : 'password'"
      :right-icon="canSeePassword ? 'eye-o' : 'closed-eye'"
      @click-right-icon="toggleShowPassword"/>
    </van-dialog>

    <!-- 编辑性别的对话框  -->
    <van-dialog
      v-model="isShowEditGender"
      title="编辑性别"
      show-cancel-button
      @confirm="editGender">
      <van-radio-group v-model="newGender">
        <van-radio :name="1">男</van-radio>
        <van-radio :name="0">女</van-radio>
      </van-radio-group>
    </van-dialog>
  </div>
</template>

<script>
import { VueCropper } from 'vue-cropper'

export default {
  data () {
    return {
      id: '',
      userInfo: {},
      isShowEditNickname: false,
      newNickname: '',
      isShowEditGender: false,
      newGender: 1,
      isShowEditPassword: false,
      newPassword: '',
      canSeePassword: false,
      // 裁剪组件的基础配置option
      option: {
        img: '', // 裁剪图片的地址
        info: true, // 裁剪框的大小信息
        outputType: 'jpeg', // 裁剪生成图片的格式
        autoCrop: true, // 是否默认生成截图框
        fixed: true,
        autoCropWidth: 150, // 默认生成截图框宽度
        autoCropHeight: 150 // 默认生成截图框高度
      },
      isShowCropper: false, // 是否显示截图框
      newHeadImgUrl: ''
    }
  },

  components: {
    VueCropper
  },

  created () {
    this.id = localStorage.getItem('user_id')
    this.getUserInfo()
  },

  methods: {
    /**
     * 网络请求
     */
    // 获取用户信息
    async getUserInfo () {
      const { data: res } = await this.$axios.get(`/user/${this.id}`)
      const { statusCode, message, data } = res
      if (statusCode !== 200) {
        return this.$toast.fail(message)
      }
      this.userInfo = data
    },

    // 修改用户信息
    async editUserInfo (userData) {
      const { data: res } = await this.$axios.post(`/user_update/${this.id}`, userData)
      const { statusCode, message } = res
      if (statusCode !== 200) {
        return this.$toast.fail(message)
      }
      this.$toast.success(message)
    },

    // 上传文件
    async uploadFile (file) {
      const { data: res } = await this.$axios.post('/upload', file)
      const { data, message, statusCode } = res
      if (statusCode !== 200) {
        return this.$toast.fail(message)
      }
      this.newHeadImgUrl = data.url
      return this.$toast.success(message)
    },

    /**
     * 业务逻辑
     */
    // 显示编辑用户昵称对话框
    showEditNicknameDia () {
      this.isShowEditNickname = true
      this.newNickname = this.userInfo.nickname
    },

    // 确认编辑用户昵称
    async editNickname () {
      await this.editUserInfo({ nickname: this.newNickname })
      this.getUserInfo()
    },

    // 显示编辑用户性别对话框
    showEditGenderDia () {
      this.isShowEditGender = true
      this.newGender = this.userInfo.gender
    },

    // 确认编辑用户性别
    async editGender () {
      await this.editUserInfo({ gender: this.newGender })
      this.getUserInfo()
    },

    // 显示编辑用户密码对话框
    showEditPasswordDia () {
      this.isShowEditPassword = true
      this.newPassword = this.userInfo.password
    },

    // 确认编辑用户密码
    async editPassword () {
      await this.editUserInfo({ password: this.newPassword })
      this.getUserInfo()
    },

    // 点击小眼睛切换显示和隐藏密码
    toggleShowPassword () {
      this.canSeePassword = !this.canSeePassword
    },

    // 关闭编辑密码对话框时恢复小眼睛的样式
    closeEditPasswordDia () {
      this.canSeePassword = false
    },

    // 选择完图片之后
    async afterRead (file) {
      this.isShowCropper = true
      this.option.img = file.content
    },

    // 取消裁切
    cancleCrop () {
      this.isShowCropper = false
      this.option.img = ''
    },

    // 确认裁切
    confirmCrop () {
      this.$refs.cropper.getCropBlob(async (fileData) => {
        const fd = new FormData()
        fd.append('file', fileData)
        await this.uploadFile(fd)
        await this.editUserInfo({ head_img: this.newHeadImgUrl })
        this.getUserInfo()
        this.isShowCropper = false
        this.option.img = ''
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.avator {
  position: relative;
  padding: 20px 0;

  img {
    margin: 0 auto;
    width: 70px;
    height: 70px;
    border-radius: 50%;
  }

  .van-uploader {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    opacity: 0;
  }
}

.vue-cropper-box {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  height: 100%;
  z-index: 999;
  .crop-btn {
    position: absolute;
    bottom: 20px;
    &.confirm-btn {
      right: 20px;
    }
    &.cancle-btn {
      left: 20px;
    }
  }
}

.van-dialog {
  padding: 0 20px;
  .van-field {
    margin: 20px 0;
    border: 1px solid #eee;
  }
}

.van-radio-group  {
  display: flex;
  margin: 20px 0;
  justify-content: space-around;
}
</style>
